package com.xidian.domain.strategy.service.armory;

import com.xidian.domain.strategy.model.entity.StrategyAwardsEntity;
import com.xidian.domain.strategy.repository.IStrategyRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.SecureRandom;
import java.util.*;

@Slf4j
@Service
public class StrategyArmory implements IStrategyArmory {

    @Resource
    private IStrategyRepository strategyRepository;

    @Override
    public boolean assembleLotteryStrategy(Long strategyId) {
        //查询策略配置
        List<StrategyAwardsEntity> strategyAwards = strategyRepository.queryStrategyAwardsList(strategyId);
        //获取最小的概率值
        BigDecimal minAwardsProbability = strategyAwards.stream()
                .map(StrategyAwardsEntity::getAwardsProbability)
                .min(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO);
        //获取概率值总和
        BigDecimal totalAwardsProbability = strategyAwards.stream()
                .map(StrategyAwardsEntity::getAwardsProbability)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //用 1 % 0.0001 获得概率范围，百分位、千分位、万分位 向上取整
        BigDecimal probabilityRange = totalAwardsProbability.divide(minAwardsProbability, 0, RoundingMode.CEILING);
        //生成奖品策略查找表
        List<Long> strategyAwardsSearchProbabilityTables = new ArrayList<>(probabilityRange.intValue());
        for (StrategyAwardsEntity strategyAwardsEntity : strategyAwards) {
            Long awardsId = strategyAwardsEntity.getAwardsId();
            BigDecimal awardsProbability = strategyAwardsEntity.getAwardsProbability();
            //计算每个概率值需要填充的表的数量
            for (int i = 0; i < probabilityRange.multiply(awardsProbability).setScale(0, RoundingMode.CEILING).intValue(); i++) {
                strategyAwardsSearchProbabilityTables.add(awardsId);
            }
        }
        //打乱顺序
        Collections.shuffle(strategyAwardsSearchProbabilityTables);
        //生成出Map集合，key值，对应的就是后续的概率值。通过概率来获得对应的奖品ID
        Map<Integer, Integer> shuffleStrategyAwardsSearchProbabilityTable = new LinkedHashMap<>();
        for (int i = 0; i < strategyAwardsSearchProbabilityTables.size(); i++) {
            shuffleStrategyAwardsSearchProbabilityTable.put(i, strategyAwardsSearchProbabilityTables.get(i).intValue());
        }
        //存放再redis中
        strategyRepository.storeStrategyAwardsProbabilityTable(strategyId, shuffleStrategyAwardsSearchProbabilityTable.size(), shuffleStrategyAwardsSearchProbabilityTable);
        return true;
    }

    @Override
    public Integer getRandomAwardsId(Long strategyId) {
        int probabilityRange = strategyRepository.getProbabilityRange(strategyId);
        return strategyRepository.getStrategyAwardsAssemble(strategyId, new SecureRandom().nextInt(probabilityRange));
    }
}
